package com.ruoyi.data.modbus;

import com.ruoyi.constant.ERPConstant;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.machine.advanced.status.domain.Status;
import com.ruoyi.machine.advanced.status.service.IStatusService;
import com.ruoyi.machine.base.device.domain.Device;
import com.ruoyi.machine.base.device.service.IDeviceService;
import com.ruoyi.produce.base.circulatingWater.domain.CirculatingWater;
import com.ruoyi.produce.base.circulatingWater.service.ICirculatingWaterService;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.code.DataType;
import com.serotonin.modbus4j.exception.ErrorResponseException;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;

import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;

public class Modbus4jRunner {
    /**
     * 数据采集并且写入数据库中
     */
    public static void collectData(IStatusService statusService, ICirculatingWaterService circulatingWaterService, IDeviceService deviceService) {
        List<Device> deviceList = deviceService.selectAllMachineByType(ERPConstant.MODBUS_MACHINE);//查询到所有有modbus通信协议ip的设备
        for (int i = 0; i < deviceList.size(); i++) {
            ModbusMaster master = Modbus4jUtils.getMaster(deviceList.get(i).getMachineIp());
            Status status = statusService.selectStatusById(deviceList.get(i).getMachineId()); //设备状态
            try {
                master.init();
                status.setCommunicateStatus(ERPConstant.COMMON_SUCCEED); //设备运行成功
                statusService.updateStatus(status); //更新机器状态
//                //读产量
//                Number output = Modbus4jUtils.readHoldingRegister(master, 1, 0x618B, DataType.TWO_BYTE_INT_UNSIGNED);
//                System.out.println("数据" + output);
//                // 存数据库
//                List<Scheduling> schedulingList = schedulingService.selectSchedulingById(shiftInfoService.createShiftInfoId(), deviceList.get(i).getMachineId());//查询出加工单和员工等信息
//                Scheduling scheduling = schedulingList.get(0);
//                if (StringUtils.isNotNull(scheduling)) {
//                    // 有排产记录的机器
//                    DataCollection dataCollection = dataCollectionService.selectDataCollectionById(shiftInfoService.createShiftInfoId(), deviceList.get(i).getMachineId());
//                    if (StringUtils.isNotNull(dataCollection)) {
//                        // 存在，更新
//                        dataCollection.setProduceNumber((Integer) output);
//                        dataCollectionService.updateDataCollection(dataCollection);
//                        System.out.println("更新成功");
//                    } else {
//                        // 新增
//                        DataCollection collection = new DataCollection(shiftInfoService.createShiftInfoId(), deviceList.get(i).getMachineId(), scheduling.getWorkSheetId(), scheduling.getStaffId(), (Integer) output);
//                        dataCollectionService.insertDataCollection(collection);
//                        System.out.println("新增成功");
//                    }
//                }
//
//                //处理警报状态
//                Number alarm1 = Modbus4jUtils.readHoldingRegister(master, 1, 0x0101, DataType.TWO_BYTE_INT_UNSIGNED);
//                Number alarm2 = Modbus4jUtils.readHoldingRegister(master, 1, 0x0102, DataType.TWO_BYTE_INT_UNSIGNED);
//                Number alarm3 = Modbus4jUtils.readHoldingRegister(master, 1, 0x0103, DataType.TWO_BYTE_INT_UNSIGNED);
//                if ((Integer) alarm1 == 0 && (Integer) alarm2 == 0 && (Integer) alarm3 == 0) {
//                    // 三个同时为0，说明没警报
//                    status.setAlarmStatus(ERPConstant.COMMON_NO);
//                    statusService.updateStatus(status); //更新机器状态
//                } else {
//                    // 有警报
//                    status.setAlarmStatus(ERPConstant.COMMON_YES);
//                    statusService.updateStatus(status); //更新机器状态
//                    System.out.println("设备" + deviceList.get(i).getMachineId() + "警报预警");
//                    // 找到哪个警报报警
//                    List<Integer> alarmList = AlarmUtil.searchAlarmedMachine((Integer) alarm1, (Integer) alarm2, (Integer) alarm3);
//                    List<String> stringList = new ArrayList<>();
//                    for (Integer item : alarmList) {
//                        String content = AlarmContent.modbusAlarmMap.get(item);
//                        stringList.add(content);
//                    }
//                    String alarmContent = AlarmUtil.arrayToString(stringList);//数组集合转成一个字符串
//                    // 存入警报记录模块
//                    MachineAlarm machineAlarm = new MachineAlarm(deviceList.get(i).getMachineId(), alarmContent);
//                    machineAlarmService.insertMachineAlarm(machineAlarm); //新增警报记录
//                }
                // 读取循环水参数
                String waterId = createWaterId();
                int[] intArray = new int[14];
                int chillerTemperature1 = (int) Modbus4jUtils.readHoldingRegister(master, 1, 0, DataType.TWO_BYTE_INT_UNSIGNED); //冷水机设定温度
                intArray[0] = chillerTemperature1;
//                System.out.println("冷水机设定温度  " + chillerTemperature1);
                int chillerTemperature2 = (int) Modbus4jUtils.readHoldingRegister(master, 1, 2, DataType.TWO_BYTE_INT_UNSIGNED); //冷冻水进水温度
                intArray[1] = chillerTemperature2;
//                System.out.println("冷冻水进水温度  " + chillerTemperature2);
                int chillerTemperature3 = (int) Modbus4jUtils.readHoldingRegister(master, 1, 6, DataType.TWO_BYTE_INT_UNSIGNED); //冷冻水出水温度
                intArray[2] = chillerTemperature3;
//                System.out.println("冷冻水出水温度  " + chillerTemperature3);
                int chillerTemperature4 = (int) Modbus4jUtils.readHoldingRegister(master, 1, 8, DataType.TWO_BYTE_INT_UNSIGNED); //冷却水进水温度
                intArray[3] = chillerTemperature4;
//                System.out.println("冷却水进水温度  " + chillerTemperature4);
                int chillerTemperature5 = (int) Modbus4jUtils.readHoldingRegister(master, 1, 10, DataType.TWO_BYTE_INT_UNSIGNED); //冷却水出水温度
                intArray[4] = chillerTemperature5;
//                System.out.println("冷却水出水温度  " + chillerTemperature5);

                int chillerPressure1 = (int) Modbus4jUtils.readHoldingRegister(master, 1, 16, DataType.TWO_BYTE_INT_UNSIGNED); //冷冻水设定压力
                intArray[5] = chillerPressure1;
//                System.out.println("冷冻水设定压力  " + chillerPressure1);
                int chillerPressure2 = (int) Modbus4jUtils.readHoldingRegister(master, 1, 12, DataType.TWO_BYTE_INT_UNSIGNED); //冷冻水实际压力
                intArray[6] = chillerPressure2;
//                System.out.println("冷冻水实际压力  " + chillerPressure2);
                int chillerPressure3 = (int) Modbus4jUtils.readHoldingRegister(master, 1, 28, DataType.TWO_BYTE_INT_UNSIGNED); //冷却水设定压力
                intArray[7] = chillerPressure3;
//                System.out.println("冷却水设定压力  " + chillerPressure3);
                int chillerPressure4 = (int) Modbus4jUtils.readHoldingRegister(master, 1, 24, DataType.TWO_BYTE_INT_UNSIGNED); //冷却水实际压力
                intArray[8] = chillerPressure4;
//                System.out.println("冷却水实际压力  " + chillerPressure4);

                boolean chillerStatus1 = Modbus4jUtils.readCoilStatus(master, 1, 14); // 冷冻水开关机
//                floatArray[9] = chillerStatus1;
//                System.out.println("冷冻水开关机  " + chillerStatus1);
                int chillerStatus2 = (int) Modbus4jUtils.readHoldingRegister(master, 1, 20, DataType.TWO_BYTE_INT_UNSIGNED); // 冷冻水系统运行
                intArray[9] = chillerStatus2;
//                System.out.println("冷冻水系统运行  " + chillerStatus2);
                boolean chillerStatus3 = Modbus4jUtils.readCoilStatus(master, 1, 26); // 冷却水开关机
//                floatArray[11] = chillerStatus3;
//                System.out.println("冷却水开关机  " + chillerStatus3);
                int chillerStatus4 = (int) Modbus4jUtils.readHoldingRegister(master, 1, 32, DataType.TWO_BYTE_INT_UNSIGNED); // 冷却水系统运行
                intArray[10] = chillerStatus4;
//                System.out.println("冷却水系统运行  " + chillerStatus4);

                int chillerAlarm1 = (int) Modbus4jUtils.readHoldingRegister(master, 1, 4, DataType.TWO_BYTE_INT_UNSIGNED); //冷水机总报警
                intArray[11] = chillerAlarm1;
//                System.out.println("冷水机总报警  " + chillerAlarm1);
                int chillerAlarm2 = (int) Modbus4jUtils.readHoldingRegister(master, 1, 18, DataType.TWO_BYTE_INT_UNSIGNED); //冷冻水总报警
                intArray[12] = chillerAlarm2;
//                System.out.println("冷冻水总报警  " + chillerAlarm2);
                int chillerAlarm3 = (int) Modbus4jUtils.readHoldingRegister(master, 1, 30, DataType.TWO_BYTE_INT_UNSIGNED); //冷却水总报警
                intArray[13] = chillerAlarm3;
//                System.out.println("冷却水总报警  " + chillerAlarm3);
                CirculatingWater circulatingWater = circulatingWaterService.selectCirculatingWaterById(waterId);
                if (StringUtils.isNotNull(circulatingWater)) {
                    // 更新
                    build(circulatingWater, intArray, chillerStatus1, chillerStatus3);
                    circulatingWaterService.updateCirculatingWater(circulatingWater);
                } else {
                    // 新增
                    CirculatingWater cw = new CirculatingWater();
                    cw.setWaterId(waterId);
                    build(cw, intArray, chillerStatus1, chillerStatus3);
                    circulatingWaterService.insertCirculatingWater(cw);
                }
            } catch (ModbusInitException e) {
//                status.setOperateStatus("0"); //运行失败
                status.setCommunicateStatus(ERPConstant.COMMON_FAIL); //通信建立失败
                statusService.updateStatus(status); //更新机器状态
                System.out.println("设备" + deviceList.get(i).getMachineId() + "运行异常");
                e.printStackTrace();
            } catch (ModbusTransportException | ErrorResponseException e) {
                status.setCommunicateStatus(ERPConstant.COMMON_FAIL); //通信失败
                statusService.updateStatus(status); //更新机器状态
                System.out.println("设备" + deviceList.get(i).getMachineId() + "读数据运行异常");
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                master.destroy();
            }
        }
    }


    /**
     * 生成循环水的id
     * @return
     */
    public static String createWaterId() {
        Calendar nowtime = new GregorianCalendar();
        String time = (String.format("%02d", nowtime.get(Calendar.YEAR)) +
                String.format("%02d", nowtime.get(Calendar.MONTH) + 1) +
                String.format("%02d", nowtime.get(Calendar.DATE)));
        return time;
    }

    /**
     * 实体类构造器
     * @param circulatingWater
     * @param intArray
     * @param chillerStatus1
     * @param chillerStatus2
     */
    public static void build(CirculatingWater circulatingWater, int[] intArray, boolean chillerStatus1, boolean chillerStatus2) {
        circulatingWater.setChillerTemperature1(intArray[0]);
        circulatingWater.setChillerTemperature2(intArray[1]);
        circulatingWater.setChillerTemperature3(intArray[2]);
        circulatingWater.setChillerTemperature4(intArray[3]);
        circulatingWater.setChillerTemperature5(intArray[4]);

        circulatingWater.setChillerPressure1(intArray[5]);
        circulatingWater.setChillerPressure2(intArray[6]);
        circulatingWater.setChillerPressure3(intArray[7]);
        circulatingWater.setChillerPressure4(intArray[8]);

        circulatingWater.setChillerStatus1(chillerStatus1);
        circulatingWater.setChillerStatus2(intArray[9]);
        circulatingWater.setChillerStatus3(chillerStatus2);
        circulatingWater.setChillerStatus4(intArray[10]);

        circulatingWater.setChillerAlarm1(intArray[11]);
        circulatingWater.setChillerAlarm2(intArray[12]);
        circulatingWater.setChillerAlarm3(intArray[13]);
    }
}
